package yagwl.client.widget;

import yagwl.client.widget.internal.YClientBundle;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.testing.StubScheduler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;

/**
 * Limits number of characters entered in a TextArea, and displays. Also
 * increase the height as you type.
 */
public class InputTextArea extends Composite {
  private final FlowPanel rootFlowPanel = new FlowPanel();
  private TextArea msgTA = new TextArea();
  private int maxChars;
  private int initialLines;
  private int lineIncrements;
  private Label charsLeftLbl;
  private boolean handlerAdded;

  public InputTextArea() {
    rootFlowPanel.add(msgTA);
    initWidget(rootFlowPanel);

    (new StubScheduler()).scheduleDeferred(new Scheduler.ScheduledCommand() {
      public void execute() {
        System.out.println("-- In execute");
        resizeHeight();
      }
    });
  }

  public InputTextArea setInitialLines(int initialLines) {
    this.initialLines = initialLines;
    msgTA.setVisibleLines(initialLines);
    return this;
  }

  public InputTextArea setLineIncrements(int lineIncrements) {
    if (lineIncrements <= 0) {
      this.lineIncrements = 0;
      return this;
    }
    this.lineIncrements = lineIncrements;
    if (!handlerAdded) {
      InputKeyUpHandler handler = new InputKeyUpHandler();
      msgTA.addKeyUpHandler(handler);
      handlerAdded = true;
    }
    return this;
  }

  public InputTextArea setMaxCharacters(int maxChars) {
    if (maxChars <= 0)
      return this;
    this.maxChars = maxChars;
    charsLeftLbl = new Label("" + maxChars);
    charsLeftLbl.setStyleName(YClientBundle.I.css().inputTextAreaCharsLeft());
    rootFlowPanel.add(charsLeftLbl);
    if (!handlerAdded) {
      InputKeyUpHandler handler = new InputKeyUpHandler();
      msgTA.addKeyUpHandler(handler);
      handlerAdded = true;
    }
    return this;
  }

  public InputTextArea setTextAreaWidth(String width) {
    msgTA.setWidth(width);
    return this;
  }

  public InputTextArea setTextAreaStyleName(String styleName) {
    msgTA.setStyleName(styleName);
    return this;
  }

  public InputTextArea setCharsLeftStyleName(String styleName) {
    if (charsLeftLbl != null)
      charsLeftLbl.setStyleName(styleName);
    return this;
  }

  public String getText() {
    String t = msgTA.getText().trim();
    if (t.length() == 0)
      return null;
    return t;
  }

  public void setText(String text) {
    msgTA.setText(text);
    updateCharsLeft();
  }

  public void clear() {
    msgTA.setText("");
    charsLeftLbl.setText("" + maxChars);
  }

  public void setFocus() {
    msgTA.setFocus(true);
  }

  private class InputKeyUpHandler implements KeyUpHandler {
    @Override
    public void onKeyUp(KeyUpEvent event) {
      InputTextArea.this.updateCharsLeft();
      InputTextArea.this.resizeHeight();
    }
  }

  private void resizeHeight() {
    msgTA.setVisibleLines(initialLines);
    while (msgTA.getElement().getScrollHeight() > msgTA.getElement()
        .getClientHeight()) {
      msgTA.setVisibleLines(msgTA.getVisibleLines() + lineIncrements);
    }
  }

  private void updateCharsLeft() {
    if (maxChars <= 0)
      return;
    int len = msgTA.getText().length();
    if (len > maxChars) {
      msgTA.setText(msgTA.getText().substring(0, maxChars));
      len = msgTA.getText().length();
    }
    charsLeftLbl.setText("" + (maxChars - len));
  }

}